﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Linq.Expressions;

namespace ClassifierLib.Classifier.Filters
{
    /// <summary>
    /// This base class represents a stage in the LCS process
    /// Derivitives are able to interact with selected rules, the global rule population, and can return a list of rules for the next filter
    /// This allows linear chains of filters to be constructed
    /// </summary>
    public abstract class RuleFilter : INotifyPropertyChanged
    {
        /// <summary>
        /// Main function of filter
        /// </summary>
        /// <param name="Population">Full population of rules</param>
        /// <param name="PopSet">PopSet rules from previous filter</param>
        /// <param name="State">Environmental state</param>
        /// <returns></returns>
        public abstract Population Apply(Population Population, Population Selected, Environment.State State, Action Action);

        private string _name;
        /// <summary>
        /// Name of the filter to display in UI
        /// </summary>
        public string Name
        {
            get
            {
                return _name;
            }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }

        private static int _iterationCount;

        /// <summary>
        /// Provides a global accessor to all filters of the current iteration of 
        /// the LCS. This is updated by the LCS.cs itself
        /// </summary>
        public static int IterationCount
        {
            get
            {
                return _iterationCount;
            }
            set
            {
                _iterationCount = value;
            }
        }


        /// <summary>
        /// This class allows the filter to construct actions, it is set to a correct instance by the LCS prior to filter exectution
        /// </summary>
        public virtual ActionFactory ActionFactory
        {
            get;
            set;
        }



        #region Implementation of INotifyPropertyChanged

        public event PropertyChangedEventHandler PropertyChanged = null;

        protected void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }

        #endregion

        #region mechanism for recording all derived types (needed for xml serialisation)
        private static List<Type> _types = new List<Type>();
        public static List<Type> RegisteredTypes
        {
            get
            {
                return _types;
            }
        }
        #endregion
    }
}
